package dataGoods

import (
	"context"
	goods_pb "mxshop/api/goods/v1"
	IGoods "mxshop/app/mxshop_api/api/internal/data/goods"
	"mxshop/app/mxshop_api/api/internal/domain/do/goods"
	"mxshop/gmicro/pkg/errors"
)

type goods struct {
	gc goods_pb.GoodsClient
}

func (g *goods) List(ctx context.Context, request *goods_pb.GoodsFilterRequest) (*doGoods.GoodDOList, error) {
	var ret doGoods.GoodDOList

	rsp, err := g.gc.GoodsList(ctx, request)
	if err != nil {
		return nil, errors.FromGrpcError(err)
	}

	for _, v := range rsp.Data {
		ret.Items = append(ret.Items, &doGoods.GoodDO{
			Id:              v.Id,
			Name:            v.Name,
			GoodsSn:         v.GoodsSn,
			ClickNum:        v.ClickNum,
			SoldNum:         v.SoldNum,
			FavNum:          v.FavNum,
			MarketPrice:     v.MarketPrice,
			ShopPrice:       v.ShopPrice,
			GoodsBrief:      v.GoodsBrief,
			GoodsDesc:       v.GoodsDesc,
			ShipFree:        v.ShipFree,
			Images:          v.Images,
			DescImages:      v.DescImages,
			GoodsFrontImage: v.GoodsFrontImage,
			IsNew:           v.IsNew,
			IsHot:           v.IsHot,
			OnSale:          v.OnSale,
			AddTime:         v.AddTime,
			Category: &doGoods.CategoryDO{
				Id:   v.Category.Id,
				Name: v.Category.Name,
			},
			Brand: &doGoods.BrandDO{
				Id:   v.Brand.Id,
				Name: v.Brand.Name,
				Logo: v.Brand.Logo,
			},
		})
	}
	ret.TotalCount = int64(rsp.Total)

	return &ret, nil
}

func (g *goods) GetBatch(ctx context.Context, ids []int64) (*doGoods.GoodDOList, error) {
	var ret doGoods.GoodDOList

	rsp, err := g.gc.BatchGetGoods(ctx, &goods_pb.BatchGoodsIdInfo{Id: ids})
	if err != nil {
		return nil, errors.FromGrpcError(err)
	}

	for _, v := range rsp.Data {
		ret.Items = append(ret.Items, &doGoods.GoodDO{
			Id:              v.Id,
			Name:            v.Name,
			GoodsSn:         v.GoodsSn,
			ClickNum:        v.ClickNum,
			SoldNum:         v.SoldNum,
			FavNum:          v.FavNum,
			MarketPrice:     v.MarketPrice,
			ShopPrice:       v.ShopPrice,
			GoodsBrief:      v.GoodsBrief,
			GoodsDesc:       v.GoodsDesc,
			ShipFree:        v.ShipFree,
			Images:          v.Images,
			DescImages:      v.DescImages,
			GoodsFrontImage: v.GoodsFrontImage,
			IsNew:           v.IsNew,
			IsHot:           v.IsHot,
			OnSale:          v.OnSale,
			AddTime:         v.AddTime,
			Category: &doGoods.CategoryDO{
				Id:   v.Category.Id,
				Name: v.Category.Name,
			},
			Brand: &doGoods.BrandDO{
				Id:   v.Brand.Id,
				Name: v.Brand.Name,
				Logo: v.Brand.Logo,
			},
		})
	}
	ret.TotalCount = int64(rsp.Total)

	return &ret, nil
}

func (g *goods) Get(ctx context.Context, id int64) (*doGoods.GoodDO, error) {
	var ret doGoods.GoodDO

	rsp, err := g.gc.GetGoodsDetail(ctx, &goods_pb.GoodInfoRequest{Id: id})
	if err != nil {
		return nil, errors.FromGrpcError(err)
	}

	ret = doGoods.GoodDO{
		Id:              rsp.Id,
		Name:            rsp.Name,
		GoodsSn:         rsp.GoodsSn,
		ClickNum:        rsp.ClickNum,
		SoldNum:         rsp.SoldNum,
		FavNum:          rsp.FavNum,
		MarketPrice:     rsp.MarketPrice,
		ShopPrice:       rsp.ShopPrice,
		GoodsBrief:      rsp.GoodsBrief,
		GoodsDesc:       rsp.GoodsDesc,
		ShipFree:        rsp.ShipFree,
		Images:          rsp.Images,
		DescImages:      rsp.DescImages,
		GoodsFrontImage: rsp.GoodsFrontImage,
		IsNew:           rsp.IsNew,
		IsHot:           rsp.IsHot,
		OnSale:          rsp.OnSale,
		AddTime:         rsp.AddTime,
		Category: &doGoods.CategoryDO{
			Id:   rsp.Category.Id,
			Name: rsp.Category.Name,
		},
		Brand: &doGoods.BrandDO{
			Id:   rsp.Brand.Id,
			Name: rsp.Brand.Name,
			Logo: rsp.Brand.Logo,
		},
	}

	return &ret, nil
}

func (g *goods) Create(ctx context.Context, request *doGoods.GoodDO) (*doGoods.GoodDO, error) {
	var ret doGoods.GoodDO

	rsp, err := g.gc.CreateGoods(ctx, &goods_pb.CreateGoodsInfo{
		Name:            request.Name,
		GoodsSn:         request.GoodsSn,
		Stocks:          request.Stocks,
		MarketPrice:     request.MarketPrice,
		ShopPrice:       request.ShopPrice,
		GoodsBrief:      request.GoodsBrief,
		GoodsDesc:       request.GoodsDesc,
		ShipFree:        request.ShipFree,
		Images:          request.Images,
		DescImages:      request.DescImages,
		GoodsFrontImage: request.GoodsFrontImage,
		IsNew:           request.IsNew,
		IsHot:           request.IsHot,
		OnSale:          request.OnSale,
		CategoryId:      request.Category.Id,
		BrandId:         request.Brand.Id,
	})
	if err != nil {
		return nil, errors.FromGrpcError(err)
	}

	ret.Id = rsp.Id

	return &ret, nil
}

func (g *goods) Update(ctx context.Context, request *doGoods.GoodDO) error {

	goodsInfo := &goods_pb.CreateGoodsInfo{
		Id:              request.Id,
		Name:            request.Name,
		GoodsSn:         request.GoodsSn,
		Stocks:          request.Stocks,
		MarketPrice:     request.MarketPrice,
		ShopPrice:       request.ShopPrice,
		GoodsBrief:      request.GoodsBrief,
		GoodsDesc:       request.GoodsDesc,
		ShipFree:        request.ShipFree,
		Images:          request.Images,
		DescImages:      request.DescImages,
		GoodsFrontImage: request.GoodsFrontImage,
		IsNew:           request.IsNew,
		IsHot:           request.IsHot,
		OnSale:          request.OnSale,
	}

	if request.Category != nil {
		goodsInfo.CategoryId = request.Category.Id
	}
	if request.Brand != nil {
		goodsInfo.BrandId = request.Brand.Id
	}

	_, err := g.gc.UpdateGoods(ctx, goodsInfo)
	if err != nil {
		return errors.FromGrpcError(err)
	}

	return nil
}

func (g *goods) Delete(ctx context.Context, id int64) error {
	_, err := g.gc.DeleteGoods(ctx, &goods_pb.DeleteGoodsInfo{Id: id})
	if err != nil {
		return errors.FromGrpcError(err)
	}
	return nil
}

func newGoods(gc goods_pb.GoodsClient) IGoods.Goods {
	return &goods{
		gc: gc,
	}
}
